﻿#region License
// Copyright © 2004 - 2010 All Right Reserved, Derek Goslin
// 
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
// 
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license
//     conditions and limitations in section 3, each contributor grants you a non-exclusive,
//     worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative 
//     works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations
//     in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its
//     licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of
//     its contribution in the software or derivative works of the contribution in the software.
// 
// 3. Conditions and Limitations
// (A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), 
//     you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. 
//     You may license other files that are entirely your own work and do not contain code from the software under any terms you choose.
// (B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
//     your patent license from such contributor to the software ends automatically.
// (D) If you distribute any portion of the software, you must retain all copyright, patent, trademark,
//     and attribution notices that are present in the software.
// (E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy 
//     of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do 
//     so under a license that complies with this license.
// (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions.
//    You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your
//    local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
#endregion

using System;

namespace DnEcuDiag.Conversion
{
    public class ME31Conversion : Convertor, IConvertor
    {
        private readonly float[] _me31AirTemp;
        private readonly float[] _me31EngineTemp;

        public ME31Conversion()
        {
            #region ME3.1 Temp

            _me31AirTemp = new[]
                               {
                                   -50f, -50f, -50f, -50f, -45f, -40f, -37.5f, -35f, -33.3f, -31.7f, -30f, -28.30f,
                                   -26.70f, -25.00f,
                                   -23.30f, -21.70f,
                                   -20f, -19f, -18f, -17f, -16f, -15f, -14f, -13f, -12f, -11f, -10f, -9.20f, -8.3f,
                                   -7.5f, -6.7f, -5.8f
                                   ,
                                   -5f, -4.2f, -3.3f, -2.5f, -1.7f, -.8f, 0f, .6f, 1.3f, 1.9f, 2.5f, 3.1f, 3.8f, 4.4f,
                                   5f, 5.6f,
                                   6.1f, 6.7f, 7.2f, 7.8f, 8.3f, 8.9f, 9.4f, 10f, 10.6f, 11.1f, 11.7f, 12.2f, 12.8f,
                                   13.3f, 13.9f,
                                   14.4f,
                                   15f, 15.5f, 16f, 16.5f, 17f, 17.5f, 18f, 18.5f, 19f, 19.5f, 20f, 20.5f, 21f, 21.5f,
                                   22f, 22.5f,
                                   23f, 23.5f, 24f, 24.5f, 25f, 25.5f, 25.90f, 26.4f, 26.4f, 26.8f, 27.3f, 27.7f, 2.82f,
                                   28.6f, 29.1f,
                                   29.5f, 30f,
                                   30.5f, 30.9f, 31.4f, 31.8f, 32.30f, 32.3f, 32.7f, 33.2f, 33.6f, 34.1f, 34.5f, 35f,
                                   35.5f, 35.9f,
                                   36.4f, 36.8f, 37.3f,
                                   37.7f, 38.2f, 38.60f, 39.1f, 39.5f, 40f, 40.5f, 40.9f, 41.4f, 41.8f, 42.3f, 42.7f,
                                   43.2f, 43.6f,
                                   44.1f, 44.5f,
                                   45f, 45.5f, 45.9f, 46.8f, 47.3f, 47.7f, 48.2f, 48.6f, 49.10f, 49.5f, 50f, 50.5f, 51f,
                                   51.5f, 52f,
                                   52.5f, 53f, 53.5f, 54f, 54.5f, 55f, 55.6f, 56.1f, 56.7f, 57.20f, 57.80f, 58.30f,
                                   58.90f, 60f, 60.6f,
                                   61.1f, 61.7f, 62.2f, 62.8f, 63.3f, 63.9f, 64.4f, 65f, 65.6f, 66.3f, 66.9f, 67.5f,
                                   68.1f, 68.8f,
                                   69.4f, 70f,
                                   70.6f, 71.3f, 71.9f, 72.5f, 73.1f, 73.8f, 74.4f, 75f, 75.7f, 76.4f, 77.1f, 77.9f,
                                   78.6f, 79.3f,
                                   80.0f, 80.8f,
                                   81.7f, 82.5f, 83.3f, 84.2f, 85f, 85.8f, 86.7f, 87.5f, 88.3f, 89.2f, 90f, 91f, 92f,
                                   93f, 94f, 95f,
                                   96f, 97f, 98f, 99f, 100f, 101.3f, 102.5f, 103.8f, 105f, 106.3f, 107.5f, 108.8f, 110f,
                                   111.7f, 113.3f
                                   , 115f,
                                   116.7f, 118.3f, 120f, 121.7f, 123.3f, 125f, 127.5f, 130f, 132.5f, 135f, 137.5f, 140f,
                                   142.5f, 145f,
                                   147.5f, 150f,
                                   150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f, 150f,
                                   150f, 150
                               };

            _me31EngineTemp = new[]
                                  {
                                      -41f, -40.8f, -40.6f, -40.4f, -40.2f, -40f, -37.5f, -35f, -32.5f, -30f, -28.36f,
                                      -26.72f, -26.72f,
                                      -25.08f, -23.43f, -21.79f, -20.15f,
                                      -19.04f, -17.92f, -16.81f, -15.69f, -14.58f, -13.46f, -12.35f, -11.23f, -10.12f,
                                      -9.29f, -8.46f,
                                      -7.63f, -6.79f, -5.96f, -5.13f, -4.30f,
                                      -3.47f, -2.64f, -1.80f, 0.97f, -0.14f, 0.45f, 1.05f, 1.64f, 2.23f, 2.82f, 3.42f,
                                      4.01f, 4.60f, 5.20f
                                      , 5.79f, 6.98f,
                                      7.57f, 8.16f, 8.75f, 9.35f, 9.94f, 10.44f, 10.94f, 11.45f, 11.95f, 12.45f, 12.95f,
                                      13.45f, 13.96f,
                                      14.46f, 14.96f,
                                      15.46f, 15.96f, 16.47f, 16.97f, 17.47f, 17.97f, 18.98f, 19.48f, 19.98f, 20.43f,
                                      20.89f, 21.34f,
                                      21.80f, 22.25f, 22.71f,
                                      23.16f, 23.62f, 24.07f, 24.53f, 24.98f, 25.44f, 25.90f, 26.35f, 26.81f, 27.27f,
                                      27.73f, 28.19f,
                                      28.65f, 29.10f, 29.56f, 30.02f,
                                      30.45f, 30.89f, 31.32f, 31.75f, 32.18f, 32.62f, 33.05f, 33.48f, 33.91f, 34.35f,
                                      34.78f, 35.21f,
                                      35.64f, 36.08f, 36.51f, 36.94f,
                                      37.37f, 37.81f, 38.24f, 38.67f, 39.10f, 39.54f, 39.97f, 40.41f, 40.84f, 41.28f,
                                      41.71f, 42.15f,
                                      42.58f, 43.02f, 43.45f, 43.89f,
                                      44.32f, 44.76f, 45.19f, 45.63f, 46.06f, 46.50f, 46.93f, 47.37f, 47.80f, 48.24f,
                                      48.67f, 49.11f,
                                      49.54f, 49.98f, 50.46f, 50.93f,
                                      51.41f, 51.98f, 52.37f, 52.84f, 53.32f, 53.80f, 54.27f, 54.75f, 55.23f, 55.71f,
                                      56.18f, 56.66f,
                                      57.14f, 57.61f, 58.09f, 58.57f,
                                      59.05f, 59.52f, 60f, 60.56f, 61.12f, 61.68f, 62.24f, 62.80f, 63.36f, 63.92f,
                                      64.48f, 65.04f, 65.60f,
                                      66.16f, 66.72f, 67.28f,
                                      67.84f, 68.40f, 68.96f, 69.52f, 70.08f, 70.74f, 71.41f, 72.07f, 72.73f, 73.40f,
                                      74.06f, 74.72f,
                                      75.39f, 76.05f, 76.71f, 77.38f,
                                      78.04f, 78.70f, 79.37f, 80.03f, 80.86f, 81.69f, 82.52f, 83.35f, 84.18f, 85.02f,
                                      85.85f, 86.68f,
                                      87.51f, 88.34f, 89.17f, 90.00f,
                                      91.00f, 91.99f, 92.99f, 93.98f, 94.98f, 95.98f, 96.97f, 97.97f, 98.96f, 99.96f,
                                      101.20f, 102.45f,
                                      103.69f, 104.94f, 106.18f, 107.42f,
                                      108.67f, 109.91f, 111.63f, 113.36f, 115.08f, 116.80f, 118.53f, 120.25f, 122.13f,
                                      124.01f, 125.88f,
                                      127.76f, 129.64f, 130.19f, 130.74f, 131.28f,
                                      131.82f, 132.37f, 132.91f, 133.46f, 134.00f, 134.55f, 135.09f, 135.64f, 136.18f,
                                      136.73f, 137.27f,
                                      137.82f, 138.36f, 138.36f, 138.91f, 139.45f, 140.00f
                                  };

            #endregion ME3.1 Temp
        }

        #region IConvertor Members

        public float Convert(int conversionId, byte[] rawData)
        {
            float result = 0;
            UInt32 rawValue = ConvertByteArray(rawData);

            switch (conversionId)
            {
                case 0:
                    result = rawValue;
                    break;
                case 80:
                    result = rawValue * .1f; // Checked OK
                    break;
                case 81:
                    result = rawValue; // Checked OK
                    break;
                case 82:
                    result = rawValue * 40; // Checked OK
                    break;
                case 83:
                    result = _me31EngineTemp[rawValue]; // Checked OK
                    break;
                case 84:
                    result = _me31AirTemp[rawValue]; // Checked OK
                    break;
                case 85:
                    result = rawValue * .1f; // Checked OK
                    break;
                case 86:
                    result = ((int)rawValue - 104) * .75f; // Checked OK
                    break;
                case 87:
                    result = rawValue * 2.66f; // Checked OK
                    break;
                case 88:
                    result = rawValue * 21.33f; // Checked OK
                    break;
                case 89:
                    result = rawValue * 80.916f / 256; // Checked OK
                    break;
                case 90:
                    result = rawValue * .75f; // Checked OK
                    break;
                case 91:
                    result = rawValue * 2.66f; // Checked OK
                    break;
                case 92:
                    result = rawValue * 85.33f; // Checked OK
                    break;
                case 93:
                    result = rawValue * 1050f / 217; // Checked OK
                    break;
                case 94:
                    result = rawValue * 4.88f; // Checked OK
                    break;
                case 95:
                    result = rawValue * .0942f; // Checked OK
                    break;
                case 96:
                    result = rawValue / 16f; // Checked OK
                    break;
                case 97:
                    result = rawValue * 1.2f; // Checked OK
                    break;
                case 98:
                    result = rawValue * 19; // Checked OK
                    break;
                case 99:
                    result = rawValue; // Checked OK
                    break;
                case 100:
                    result = rawValue * 80.916f / 32767; // Checked OK
                    break;
                case 101:
                    result = rawValue * 100f / 255; // Checked OK
                    break;
                case 102:
                    result = rawValue * 2.66f; // Checked OK
                    break;
                case 103:
                    result = rawValue * 100f / 1023; // Checked OK
                    break;
                case 104:
                    result = rawValue * 100f / 255; // Checked OK
                    break;
                case 105:
                    result = rawValue * 100f / 215; // Checked OK
                    break;
                case 106:
                    result = rawValue / 327.67f; // Checked OK
                    break;
                case 107:
                    result = rawValue * 80.916f / 32767; // Checked OK
                    break;
                case 108:
                    result = rawValue / 327.67f; // Checked OK
                    break;
                case 109:
                    result = rawValue / 65536f + .50f; // Checked OK
                    break;
                case 110:
                    if ((rawValue & 0x8000) == 0)
                    {
                        result = rawValue * 2.66f;
                    }
                    else
                    {
                        rawValue = (~rawValue) & 0xFFFF; // same as 16bit int invert.  
                        result = (rawValue + 1) * -2.66f;
                    }
                    break;
                case 111:
                    result = rawValue * 80.916f / 32767; // Checked OK
                    break;
                case 112:
                    result = rawValue; // Checked OK
                    break;
                case 113:
                    result = rawValue * 2.66f; // Checked OK
                    break;
                case 114:
                    result = (int)rawValue - 40; // Checked OK
                    break;
                case 115:
                    result = rawValue * 40;
                    break;
            }

            return result;
        }

        #endregion
    }
}
